package com.base.pub.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Date;

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.lang3.ArrayUtils;

/**
 * 
 * Class Name: Utils.java
 * 
 * @author songxy DateTime 2016年5月20日 上午10:50:38
 * @company winter
 * @email thinkdata@163.com
 * @version 1.0
 */
public final class Utils {

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
			"yyyy年MM月dd日 HH时mm分ss秒");

	private static final char[] hexChars = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static String convertIntIpAddress(int ipAdress) {
		return (ipAdress & 0xFF) + "." + ((ipAdress >> 8) & 0xFF) + "."
				+ ((ipAdress >> 16) & 0xFF) + "." + (ipAdress >> 24 & 0xFF);
	}

	/**
	 *
	 * Description: Mac地址转换字节数组
	 * 
	 * @author songxy DateTime 2015年12月3日 上午11:28:30
	 * @param macAddr
	 * @return
	 */
	public static byte[] convertMacAddrToBytes(String macAddr) {
		String[] ips = macAddr.split(":|\\.");
		if (ips == null || ips.length != 6)
			throw new RuntimeException("Mac 格式出错" + macAddr);
		byte[] result = new byte[6];
		for (int i = 0; i < result.length; i++) {
			result[i] = (byte) Integer.parseInt(ips[i], 16);
		}
		return result;
	}

	/**
	 * 地址字符串转字节数组
	 * 
	 * @param ip
	 * @return
	 */
	public static byte[] convertIpToBytes(String ip) {
		String[] ips = ip.split(":|\\.");
		if (ips != null && ips.length == 4) {
			byte[] result = new byte[ips.length];
			for (int i = 0; i < result.length; i++) {
				result[i] = (byte) Integer.parseInt(ips[i]);
			}
			return result;
		} else {
			throw new RuntimeException("IP 格式出错" + ip);
		}
	}

	/**
	 * 长整型转换，低字节在前，高字节在后
	 * 
	 * @param data
	 * @param length
	 * @return
	 */
	public static byte[] long2LHByte(long data, int length) {
		if (length > 8)
			throw new RuntimeException("Length " + length + " Overflow 8 num");
		byte[] result = new byte[length];
		for (int i = 0; i < length; i++) {
			result[i] = (byte) (data >> 8 * i & 0xff);
		}
		return result;
	}

	/**
	 * 长整型转换，高字节在前，低字节在后
	 * 
	 * @param data
	 * @param length
	 * @return
	 */
	public static byte[] long2HLByte(long data, int length) {
		if (length > 8)
			throw new RuntimeException("Length " + length + " Overflow 8 num");
		byte[] result = new byte[length];
		for (int i = 0; i < length; i++) {
			result[i] = (byte) (data >> 8 * (length - i) & 0xff);
		}
		return result;
	}

	// FIXME: 2016/3/16 bug 多个字节拷贝出错
	// public static byte[] intToByte(int data, int length) {
	// byte[] result = new byte[length];
	// byte[] temp = Utils.int2byte(data);
	// System.arraycopy(temp, 0, result, 0, result.length);
	// return result;
	// }

	/**
	 * 字节数组转字符串
	 *
	 * @param data
	 * @return
	 */
	public static String encodeHexStr(byte[] data) {
		return new String(encodeHex(data));
	}

	/**
	 * 字符串转字节数组
	 *
	 * @param data
	 * @return
	 */
	public static byte[] decodeHexStr(String data) {
		return decodeHex(data.toCharArray());
	}

	/**
	 *
	 * Description:
	 * 
	 * @author songxy DateTime 2016年3月24日 下午4:12:39
	 * @param data
	 *            原始数据
	 * @param num
	 *            分片长度
	 * @return
	 */
	public static byte[][] transfer2byteArray(byte[] data, int num) {
		ArrayList<byte[]> temp = new ArrayList();
		int[] temp1;
		for (int i = 0; i < data.length / num; i++) {
			temp1 = new int[num];
			// System.arraycopy(data, i*num, temp1, 0, num);
			temp.add(Arrays.copyOfRange(data, i * num, i * num + num));
		}
		return temp.toArray(new byte[0][0]);
	}

	/**
	 * byte数组转int
	 *
	 * @param b
	 * @return
	 */
	public static int byte2Int(byte[] b) {
		if (b.length == 1) {
			return b[0] & 0xff;
		} else if (b.length == 2) {
			return (b[1] & 0xff << 8) | (b[0] & 0xff);
		} else if (b.length == 3) {
			return (b[0] & 0xff << 16) | (b[1] & 0xff << 8) | (b[3] & 0xff);
		} else if (b.length == 4) {
			return ((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16)
					| ((b[2] & 0xff) << 8) | (b[3] & 0xff);
		} else {
			// Log.d("Utils", "byte length > 4 or < 1");
			return -1;
		}
	}

	public static int lhByte2Int(byte[] b) {
		if (b.length == 1) {
			return b[0] & 0xff;
		} else if (b.length == 2) {
			return (b[0] & 0xff << 8) | (b[1] & 0xff);
		} else if (b.length == 3) {
			return (b[0] & 0xff << 16) | (b[1] & 0xff << 8) | (b[2] & 0xff);
		} else if (b.length == 4) {
			return ((b[3] & 0xff) << 24) | ((b[2] & 0xff) << 16)
					| ((b[1] & 0xff) << 8) | (b[0] & 0xff);
		} else {
			throw new RuntimeException("byte length > 4 or < 1");
		}
	}

	/**
	 * 整型转字节，高字节低字节
	 *
	 * @param i
	 * @return
	 */
	public static byte[] int2HLbyte(int i) {
		byte[] b = new byte[4];
		for (int j = 0; j < 4; j++) {
			b[j] = (byte) (i >> 8 * (3 - j) & 0xff);
		}
		return b;
	}

	/**
	 * 整型转字节，低字节高字节
	 *
	 * @param i
	 * @return
	 */
	public static byte[] int2LHbyte(int i) {
		byte[] b = new byte[4];
		for (int j = 0; j < 4; j++) {
			b[j] = (byte) (i >> 8 * 3 & 0xff);
		}
		return b;
	}

	/**
	 * 整型转字节，低字节高字节
	 *
	 * @param i
	 * @return
	 */
	public static byte[] int2LHbyte(short i) {
		byte[] b = new byte[2];
		for (int j = 0; j < 2; j++) {
			b[j] = (byte) (i >> 8 * 3 & 0xff);
		}
		return b;
	}

	/**
	 * 整型转字节，高字节低字节
	 *
	 * @param i
	 * @return
	 */
	public static byte[] int2HLbyte(short i) {
		byte[] b = new byte[2];
		for (int j = 0; j < 2; j++) {
			b[j] = (byte) (i >> 8 * (j - 3) & 0xff);
		}
		return b;
	}

	public static byte[] float2LHbyte(float i) {
		return int2LHbyte(Float.floatToRawIntBits(i));
	}

	public static byte[] float2HLbyte(float i) {
		return int2HLbyte(Float.floatToRawIntBits(i));
	}

	/**
	 * 二进制转换十六进制
	 *
	 * @param data
	 * @return
	 */
	public static String byte2HexString(byte[] data) {
		StringBuffer sb = new StringBuffer();
		if (data == null || data.length == 0)
			return null;
		for (int i = 0; i < data.length; i++) {
			if (i == 0) {
				sb.append("0x");
			}
			String temp = Integer.toHexString(data[i] & 0xff);
			if (temp.length() < 2) {
				sb.append(0);
			}
			sb.append(temp);
		}
		return sb.toString();
	}

	/**
	 * 返回当前时间
	 * 
	 * @return
	 */
	public static String formatSetTime(long time) {
		return dateFormat.format(new Date(time));
	}

	public static String formatSetTime(Date time) {
		return dateFormat.format(time);
	}

	/**
	 * 字节转16进制
	 *
	 * @param data
	 * @return
	 */
	public static String bytes2HexStr(byte[] data) {
		if (data == null)
			return null;
		else if (data.length > 0) {
			String result = new String();
			for (int i = 0; i < data.length; i++) {
				result += Integer.toHexString(data[i]);
			}
			return result;
		} else {
			return "";
		}
	}

	public static byte[] getBytesArray(byte[] data, int pos, int range) {
		return Arrays.copyOfRange(data, pos, range);
	}

	public static byte[] getBytesArray1(byte[] data, int pos, int size) {
		byte[] temp = new byte[size];
		System.arraycopy(data, pos, temp, 0, size);
		return temp;
	}

	private static char[] encodeHex(byte[] data) {
		char[] result = new char[data.length << 1];
		for (int i = 0, j = 0; i < data.length; i++) {
			result[j++] = hexChars[(data[i] & 0xF0) >>> 4];
			result[j++] = hexChars[(data[i] & 0x0F)];
		}
		return result;
	}

	private static byte[] decodeHex(char[] data) {
		byte[] result = new byte[data.length >> 1];
		for (int i = 0, j = 0; j < data.length; i++) {
			int temp = toDigit(data[j], j) << 4;
			j++;
			temp = temp | (toDigit(data[j], j));
			j++;
			result[i] = (byte) (temp & 0xff);
		}
		return result;
	}

	private static int toDigit(char ch, int idx) {
		int digit = Character.digit(ch, 16);
		if (digit == -1) {
			throw new RuntimeException("Illegal hexadecimal character " + ch
					+ " at " + idx);
		}
		return digit;
	}

	public static int[] getBytes(Object[] data) {
		int[] temp = new int[data.length];
		for (int i = 0; i < data.length; i++) {
			temp[i] = (int) data[i];
		}
		return temp;
	}

	public static String transferBitToHexString(int[] data) {
		BitSet bs = new BitSet(data.length);

		for (int i = 0; i < data.length; i++) {
			bs.set(data[i]);
		}

		return DatatypeConverter.printHexBinary(bs.toByteArray());
	}

	public static String transferReverse16BitTohexString(int[] data) {
		if (data.length == 0)
			return "0000";

		BitSet bs = new BitSet();

		for (int i = 0; i < data.length; i++) {
			bs.set(data[i]);
		}

		byte[] result = bs.toByteArray();

		if (result.length == 1) {
			result = ArrayUtils.addAll(result, new byte[1]);
		}

		ArrayUtils.reverse(result);

		return DatatypeConverter.printHexBinary(result);
	}

	public static String transfer16BitTohexString(byte[] data) {
		BitSet bs = new BitSet(data.length);

		for (int i = 0; i < data.length; i++) {
			bs.set(data[i]);
		}

		return DatatypeConverter.printHexBinary(bs.toByteArray());
	}

	public static byte[] transferHexStringToBits(String data) {
		return DatatypeConverter.parseHexBinary(data);
	}

	/**
	 * 
	 * Description:客户端那边还是有小端
	 * 
	 * @author songxy DateTime 2016年11月4日 下午5:27:16
	 * @param data
	 * @return
	 */
	public static int[] bytesToBitArray(byte[] data) {
		if (data.length == 2) {
			return ArrayUtils.addAll(bits(data[1]), bits(data[0]));
		}
		return null;
	}

	private static int[] bits(byte b) {
		int n = 8;
		final int[] set = new int[n];
		while (--n >= 0) {
			set[n] = (b & 0x80) != 0 ? 1 : 0;
			b <<= 1;
		}
		return set;
	}

	public static int[] transferFromBytes(byte[] data) {
		int[] result = new int[data.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = data[i];
		}
		return result;
	}

	public static boolean isEmpty(CharSequence str) {
		if (str == null || str.length() == 0)
			return true;
		else
			return false;
	}

}
